﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using System.Linq;
using System.Globalization;
using System.Collections.Specialized;
using System.Windows.Data;

namespace Gmantis.Controls
{
    [TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates"), TemplateVisualState(Name = "Focused", GroupName = "FocusStates"), StyleTypedProperty(Property = "SeparatorStyle", StyleTargetType = typeof(Separator)), StyleTypedProperty(Property = "FirstLevelStyle", StyleTargetType = typeof(MenuItem)), StyleTypedProperty(Property = "NonFirstLevelStyle", StyleTargetType = typeof(MenuItem))]
    public class Menu : HierarchicalPresenter
    {
        // Fields
        private Popup _autoClosePopup;
        private Canvas _bottomArea;
        private Dictionary<string, List<MenuItem>> _checkGRoups;
        private MenuItem _highlightedItem;
        private bool _isLostFocusTimerTriggerred;
        private Panel _itemsPanel;
        private MenuItem _lastFocus;
        private Canvas _leftArea;
        private DispatcherTimer _lostFocusTimer;
        private Canvas _mainArea;
        private double _prevMenuHeight;
        private double _prevMenuWidth;
        private double _prevRootHeight;
        private double _prevRootWidth;
        private Canvas _rightArea;
        private Canvas _topArea;
        public static readonly DependencyProperty AutoCloseProperty = DependencyProperty.Register("AutoClose", typeof(bool), typeof(Menu), new PropertyMetadata(false, new PropertyChangedCallback(Menu.OnAutoClosePropertyChanged)));
        public static readonly DependencyProperty DetectBoundariesProperty = DependencyProperty.Register("DetectBoundaries", typeof(bool), typeof(Menu), new PropertyMetadata(false));
        public static readonly DependencyProperty DisabledCuesVisibilityProperty = DependencyProperty.Register("DisabledCuesVisibility", typeof(Visibility), typeof(Menu), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty FirstLevelStyleProperty = DependencyProperty.Register("FirstLevelStyle", typeof(Style), typeof(Menu), null);
        public static readonly DependencyProperty FocusCuesVisibilityProperty = DependencyProperty.Register("FocusCuesVisibility", typeof(Visibility), typeof(Menu), new PropertyMetadata(Visibility.Visible));
        public static readonly DependencyProperty HighlightedBackgroundProperty = DependencyProperty.Register("HighlightedBackground", typeof(Brush), typeof(Menu), null);
        public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.Register("IsFocused", typeof(bool), typeof(Menu), new PropertyMetadata(new PropertyChangedCallback(Menu.OnIsFocusedPropertyChanged)));
        public static readonly DependencyProperty MenuOpenDelayProperty = DependencyProperty.Register("MenuOpenDelay", typeof(int), typeof(Menu), new PropertyMetadata(600));
        public static readonly DependencyProperty NonFirstLevelStyleProperty = DependencyProperty.Register("NonFirstLevelStyle", typeof(Style), typeof(Menu), null);
        public static readonly DependencyProperty OpenedBackgroundProperty = DependencyProperty.Register("OpenedBackground", typeof(Brush), typeof(Menu), null);
        public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(Menu), new PropertyMetadata(Orientation.Horizontal, new PropertyChangedCallback(Menu.OnOrientationPropertyChanged)));
        public static readonly DependencyProperty SeparatorStyleProperty = DependencyProperty.Register("SeparatorStyle", typeof(Style), typeof(Menu), null);
        public static readonly DependencyProperty SubMenuMaxHeightProperty = DependencyProperty.Register("SubMenuMaxHeight", typeof(double), typeof(Menu), new PropertyMetadata((double)1.0 / (double)0.0));

        // Events
        public event EventHandler<EventArgs> AutoClosed;

        public event EventHandler<CancelEventArgs> AutoClosing;

        public event EventHandler<SourcedEventArgs> ItemChecked;

        public event EventHandler<SourcedEventArgs> ItemClick;

        public event EventHandler<SourcedEventArgs> ItemClosed;

        public event EventHandler<CancelSourceEventArgs> ItemClosing;

        public event EventHandler<SourcedEventArgs> ItemOpened;

        public event EventHandler<CancelSourceEventArgs> ItemOpening;

        public event EventHandler<SourcedEventArgs> ItemUnchecked;

        // Methods
        public Menu()
        {
            RoutedEventHandler handler = null;
            this._checkGRoups = new Dictionary<string, List<MenuItem>>();
            base.DefaultStyleKey = typeof(Menu);
            if (handler == null)
            {
                handler = (param0, param1) => this.ChangeVisualStateFocus(false);
            }
            base.Loaded += handler;
            base.GotFocus += new RoutedEventHandler(this.Control_GotFocus);
            base.LostFocus += new RoutedEventHandler(this.Control_LostFocus);
            this.SetCustomDefaultValues();
        }

        private void AttachAutoCloseAreas()
        {
            this._leftArea.MouseLeftButtonDown += new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            this._rightArea.MouseLeftButtonDown += new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            this._topArea.MouseLeftButtonDown += new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            this._bottomArea.MouseLeftButtonDown += new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            base.LayoutUpdated += new EventHandler(this.Menu_LayoutUpdated);
        }

        private void AutoCloseArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            CancelEventArgs args = new CancelEventArgs
            {
                Cancel = false
            };
            this.OnAutoClosing(args);
            if (!args.Cancel)
            {
                this.DetachAutoCloseAreas();
                this.CloseMenu();
                this.OnAutoClosed(new EventArgs());
            }
        }

        internal bool BelongsToMenu(FrameworkElement target)
        {
            bool flag = false;
            if (target != null)
            {
                if (target == this)
                {
                    return true;
                }
                IList<FrameworkElement> allParents = this.GetAllParents(target);
                if (allParents.Contains(this))
                {
                    return true;
                }
                MenuItem item = allParents.FirstOrDefault<FrameworkElement>(fe => typeof(MenuItem).IsAssignableFrom(fe.GetType())) as MenuItem;
                if ((item != null) && (item.Menu == this))
                {
                    flag = true;
                }
            }
            return flag;
        }

        private void Control_GotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            this.IsFocused = true;
        }

        private void Control_LostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            this.IsFocused = false;
        }

        private void Menu_LayoutUpdated(object sender, EventArgs e)
        {
            FrameworkElement element = this.GetRootVisual() as FrameworkElement;
            if (((this._prevRootHeight != element.ActualHeight) || (this._prevRootWidth != element.ActualWidth)) || ((this._prevMenuWidth != base.ActualWidth) || (this._prevMenuHeight != base.ActualHeight)))
            {
                this._prevRootHeight = element.ActualHeight;
                this._prevRootWidth = element.ActualWidth;
                this._prevMenuWidth = base.ActualWidth;
                this._prevMenuHeight = base.ActualHeight;
                this.UpdateAutoCloseAreas();
            }
        }

        protected void ChangeVisualStateFocus(bool useTransitions)
        {
            if (!this.IsFocused)
            {
                VisualStateHelper.GoToState(this, "Unfocused", useTransitions);
            }
            if (this.IsFocused)
            {
                VisualStateHelper.GoToState(this, "Focused", useTransitions);
            }
        }

        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            base.ClearContainerForItemOverride(element, item);
            MenuItem item2 = element as MenuItem;
            if ((item2 != null) && !PlatformIndependent.IsInDesignMode(this))
            {
                item2.UpdateGroupChecks(item2.GroupName, string.Empty);
            }
        }

        internal virtual void CloseMenu()
        {
            foreach (MenuItem item in this.MenuItems)
            {
                CancelSourceEventArgs e = new CancelSourceEventArgs
                {
                    Source = item,
                    Cancel = false
                };
                item.OnSubmenuClosing(e);
            }
            if (this.HighlightedItem != null)
            {
                this.HighlightedItem.IsHighlighted = false;
                this.HighlightedItem = null;
            }
        }

        private void CreateAutoCloseAreas()
        {
            this._mainArea = new Canvas();
            Canvas canvas = new Canvas
            {
                Background = new SolidColorBrush(Colors.Transparent)
            };
            this._leftArea = canvas;
            Canvas canvas2 = new Canvas
            {
                Background = new SolidColorBrush(Colors.Transparent)
            };
            this._rightArea = canvas2;
            Canvas canvas3 = new Canvas
            {
                Background = new SolidColorBrush(Colors.Transparent)
            };
            this._topArea = canvas3;
            Canvas canvas4 = new Canvas
            {
                Background = new SolidColorBrush(Colors.Transparent)
            };
            this._bottomArea = canvas4;
            this._mainArea.Children.Add(this._leftArea);
            this._mainArea.Children.Add(this._rightArea);
            this._mainArea.Children.Add(this._topArea);
            this._mainArea.Children.Add(this._bottomArea);
            this._autoClosePopup = new Popup();
            this._autoClosePopup.IsOpen = true;
            this._autoClosePopup.Child = this._mainArea;
        }

        private void DetachAutoCloseAreas()
        {
            this._leftArea.MouseLeftButtonDown -= new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            this._rightArea.MouseLeftButtonDown -= new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            this._topArea.MouseLeftButtonDown -= new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            this._bottomArea.MouseLeftButtonDown -= new MouseButtonEventHandler(this.AutoCloseArea_MouseLeftButtonDown);
            base.LayoutUpdated -= new EventHandler(this.Menu_LayoutUpdated);
        }

        private void EnsureVisible(MenuItem menuItem)
        {
            this.OpenHierarchy(menuItem);
        }

        private IList<FrameworkElement> GetAllParents(FrameworkElement elem)
        {
            List<FrameworkElement> list = new List<FrameworkElement>();
            if (elem != null)
            {
                FrameworkElement parent;
                FrameworkElement reference = elem;
                for (bool flag = false; !flag; flag = parent == null)
                {
                    parent = VisualTreeHelper.GetParent(reference) as FrameworkElement;
                    parent = parent ?? (reference.Parent as Popup);
                    if (parent != null)
                    {
                        reference = parent;
                        list.Add(reference);
                    }
                }
            }
            return list;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new MenuItem();
        }

        private DataTemplate GetItemDataTemplate(MenuItem menuItem, object dataItem)
        {
            DataTemplate itemTemplate = null;
            if (base.ItemTemplateSelector != null)
            {
                itemTemplate = base.ItemTemplateSelector.SelectTemplate(dataItem, menuItem);
            }
            if (base.ItemTemplate != null)
            {
                itemTemplate = base.ItemTemplate;
            }
            return itemTemplate;
        }

        internal void HideAutoCloseAreas()
        {
            if ((this._autoClosePopup != null) && !this.IsSubmenuOpen)
            {
                this.DetachAutoCloseAreas();
                this._autoClosePopup.IsOpen = false;
            }
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return ((item is MenuItem) || (item is Separator));
        }

        internal void MoveToGroupName(string oldGroup, string newGroup, MenuItem item)
        {
            List<MenuItem> list;
            if (!string.IsNullOrEmpty(oldGroup) && this._checkGRoups.TryGetValue(oldGroup, out list))
            {
                list.Remove(item);
                if (list.Count == 0)
                {
                    this._checkGRoups.Remove(oldGroup);
                }
            }
            if (!string.IsNullOrEmpty(newGroup))
            {
                if (!this._checkGRoups.ContainsKey(newGroup))
                {
                    this._checkGRoups.Add(newGroup, new List<MenuItem>());
                }
                this._checkGRoups[newGroup].Add(item);
            }
        }

        public override void OnApplyTemplate()
        {
            this.OnBeforeApplyTemplate();
            string str = string.Empty;
            base.OnApplyTemplate();
            if (!string.IsNullOrEmpty(str))
            {
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to Menu.\nDetails: {0}", new object[] { str }));
                }
            }
            else
            {
                this.ChangeVisualStateFocus(false);
            }
        }

        protected virtual void OnAutoCloseChanged(bool oldValue)
        {
        }

        protected virtual void OnAutoClosed(EventArgs e)
        {
            if (this.AutoClosed != null)
            {
                this.AutoClosed(this, e);
            }
        }

        private static void OnAutoClosePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Menu menu = d as Menu;
            bool oldValue = (bool)e.OldValue;
            menu.OnAutoCloseChanged(oldValue);
        }

        protected virtual void OnAutoClosing(CancelEventArgs e)
        {
            if (this.AutoClosing != null)
            {
                this.AutoClosing(this, e);
            }
        }

        private void OnBeforeApplyTemplate()
        {
            this._itemsPanel = null;
        }

        internal virtual void OnGotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            if ((e == null) || (e.OriginalSource == this))
            {
                if (!this._isLostFocusTimerTriggerred)
                {
                    this._lostFocusTimer.Stop();
                }
                if ((this.MenuItems.Count > 0) && (this.HighlightedItem == null))
                {
                    if (this._lastFocus == null)
                    {
                        ((MenuItem)this.MenuItems[0]).IsHighlighted = true;
                    }
                    else
                    {
                        this._lastFocus.IsHighlighted = true;
                    }
                }
            }
        }

        private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as Menu).ChangeVisualStateFocus(true);
        }

        protected internal virtual void OnItemChecked(SourcedEventArgs e)
        {
            if (this.ItemChecked != null)
            {
                this.ItemChecked(this, e);
            }
        }

        protected internal virtual void OnItemClick(SourcedEventArgs e)
        {
            if (this.ItemClick != null)
            {
                this.ItemClick(this, e);
            }
        }

        protected internal virtual void OnItemClosed(SourcedEventArgs e)
        {
            if (this.ItemClosed != null)
            {
                this.ItemClosed(this, e);
            }
        }

        protected internal virtual void OnItemClosing(CancelSourceEventArgs e)
        {
            if (this.ItemClosing != null)
            {
                this.ItemClosing(this, e);
            }
        }

        protected internal virtual void OnItemOpened(SourcedEventArgs e)
        {
            if (this.ItemOpened != null)
            {
                this.ItemOpened(this, e);
            }
        }

        protected internal virtual void OnItemOpening(CancelSourceEventArgs e)
        {
            if (this.ItemOpening != null)
            {
                this.ItemOpening(this, e);
            }
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);
            IList list = (e.Action == NotifyCollectionChangedAction.Reset) ? base.Items : e.NewItems;
            if (list != null)
            {
                foreach (object obj2 in list)
                {
                    HierarchicalPresenter presenter = obj2 as HierarchicalPresenter;
                    if (presenter != null)
                    {
                        presenter.InitializePresenter(this, this);
                    }
                    MenuItem item = obj2 as MenuItem;
                    if (item != null)
                    {
                        this.MoveToGroupName(item.GroupName, item.GroupName, item);
                        this.UpdateGroupChecks(item);
                        foreach (MenuItem item2 in item.ToList<MenuItem>())
                        {
                            this.MoveToGroupName(item2.GroupName, item2.GroupName, item2);
                            this.UpdateGroupChecks(item2);
                        }
                    }
                }
            }
        }

        protected internal virtual void OnItemUnchecked(SourcedEventArgs e)
        {
            if (this.ItemUnchecked != null)
            {
                this.ItemUnchecked(this, e);
            }
        }

        internal virtual void OnKeyDown(KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                this.CloseMenu();
            }
            else if ((this.HighlightedItem != null) && (e.Key != Key.Enter))
            {
                MenuItem menuItem = this.HighlightedItem.HandleKey(e.Key);
                if (this.HighlightedItem.ParentItem == menuItem)
                {
                    CancelSourceEventArgs args = new CancelSourceEventArgs
                    {
                        Source = menuItem,
                        Cancel = false
                    };
                    menuItem.OnSubmenuClosing(args);
                }
                this.EnsureVisible(menuItem);
                menuItem.IsHighlighted = true;
            }
        }

        internal virtual void OnKeyUp(KeyEventArgs e)
        {
            if ((this.HighlightedItem != null) && (e.Key == Key.Enter))
            {
                this.HighlightedItem.OnMouseClick(null, null);
            }
        }

        internal virtual void OnLostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            if ((e == null) || (e.OriginalSource == this))
            {
                FrameworkElement focusedElement = FocusManager.GetFocusedElement() as FrameworkElement;
                if ((focusedElement == null) || !this.BelongsToMenu(focusedElement))
                {
                    this._lostFocusTimer.Start();
                    this._isLostFocusTimerTriggerred = false;
                }
                else
                {
                    this._lastFocus = this.HighlightedItem;
                }
            }
        }

        private void OnOrientationChanged(Orientation oldValue)
        {
            this.SetPanel();
        }

        private static void OnOrientationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Menu menu = d as Menu;
            Orientation oldValue = (Orientation)e.OldValue;
            menu.OnOrientationChanged(oldValue);
        }

        private void OpenHierarchy(MenuItem menuItem)
        {
            if (!menuItem.IsFirstLevel && !menuItem.ParentItem.IsSubmenuOpen)
            {
                this.OpenHierarchy(menuItem.ParentItem);
                CancelSourceEventArgs e = new CancelSourceEventArgs
                {
                    Source = menuItem.ParentItem,
                    Cancel = false
                };
                menuItem.ParentItem.OnSubmenuOpening(e);
            }
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            this.SetPanel();
            MenuItem menuItem = element as MenuItem;
            if (menuItem != null)
            {
                base.PrepareContainerForItemOverride(element, item);
                menuItem.IsFirstLevel = true;
                if (menuItem != item)
                {
                    DataTemplate itemDataTemplate = this.GetItemDataTemplate(menuItem, item);
                    if (itemDataTemplate is HierarchicalDataTemplate)
                    {
                        HierarchicalDataTemplate template2 = itemDataTemplate as HierarchicalDataTemplate;
                        menuItem.SetBinding(ItemsControl.ItemsSourceProperty, template2.ItemsSource);
                        if (template2.ItemTemplate == null)
                        {
                            menuItem.ItemTemplate = base.ItemTemplate;
                        }
                        else
                        {
                            menuItem.ItemTemplate = template2.ItemTemplate;
                        }
                    }
                }
                if ((menuItem.Style == null) && (this.FirstLevelStyle != null))
                {
                    menuItem.Style = this.FirstLevelStyle;
                }
                menuItem.MenuBehavior = new MenuItemFirstLevel(menuItem);
                menuItem.SetBinding<Menu>(Control.FontFamilyProperty, this, m => m.FontFamily);
                menuItem.SetBinding<Menu>(Control.FontSizeProperty, this, m => m.FontSize);
                menuItem.SetBinding<Menu>(Control.FontStretchProperty, this, m => m.FontStretch);
                menuItem.SetBinding<Menu>(Control.FontStyleProperty, this, m => m.FontStyle);
                menuItem.SetBinding<Menu>(Control.FontWeightProperty, this, m => m.FontWeight);
                menuItem.SetBinding<Menu>(Control.BackgroundProperty, this, m => m.Background);
                menuItem.SetBinding<Menu>(Control.ForegroundProperty, this, m => m.Foreground);
                menuItem.SetBinding<Menu>(MenuItem.HeaderBackgroundProperty, this, m => m.Background);
                menuItem.SetBinding<Menu>(MenuItem.HeaderForegroundProperty, this, m => m.Foreground);
                menuItem.SetBinding<Menu>(Control.BorderBrushProperty, this, m => m.BorderBrush);
                menuItem.SetBinding<Menu>(UIElement.OpacityProperty, this, m => m.Opacity);
                menuItem.SetBinding<Menu>(MenuItem.HighlightedBackgroundProperty, this, m => m.HighlightedBackground);
                menuItem.SetBinding<Menu>(MenuItem.OpenedBackgroundProperty, this, m => m.OpenedBackground);
                menuItem.SetBinding<Menu>(MenuItem.SubMenuMaxHeightProperty, this, m => m.SubMenuMaxHeight);
                menuItem.SetBinding<Menu>(Control.IsEnabledProperty, this, m => m.IsEnabled);
                menuItem.UpdateGroupChecks(string.Empty, menuItem.GroupName);
            }
            Separator target = item as Separator;
            if (target != null)
            {
                Binding binding = new Binding
                {
                    Converter = CustomConverter.Create((value, type, parameter, culture) => (((Orientation)value) == Orientation.Horizontal) ? Orientation.Vertical : Orientation.Horizontal)
                };
                target.SetBinding(Separator.OrientationProperty, binding.From<Menu>(this, x => x.Orientation));
                target.Style = this.SeparatorStyle;
                target.SetBinding<Menu>(Control.BackgroundProperty, this, m => m.Background);
            }
        }

        private void SetCustomDefaultValues()
        {
            base.IsTabStop = true;
            base.TabNavigation = KeyboardNavigationMode.Once;
            base.MouseEnter += (s, e) => base.IsMouseOver = true;
            base.MouseLeave += (s, e) => base.IsMouseOver = false;
            base.KeyDown += (s, e) => this.OnKeyDown(new Gmantis.Controls.KeyEventArgs(e));
            base.KeyUp += (s, e) => this.OnKeyUp(new Gmantis.Controls.KeyEventArgs(e));
            base.LostFocus += new RoutedEventHandler(this.OnLostFocus);
            base.GotFocus += new RoutedEventHandler(this.OnGotFocus);
            base.InitializePresenter(this, null);
            this._lostFocusTimer = new DispatcherTimer();
            this._lostFocusTimer.Interval = new TimeSpan(0, 0, 0, 0, 150);
            this._lostFocusTimer.Tick += new EventHandler(this.timer_Tick);
        }

        private void SetMenuOpenDelayValue(int value)
        {
            base.SetValue(MenuOpenDelayProperty, Math.Max(0, value));
        }

        private void SetPanel()
        {
            if ((this._itemsPanel == null) && (base.ItemContainerGenerator.ContainerFromIndex(0) != null))
            {
                this._itemsPanel = VisualTreeHelper.GetParent(base.ItemContainerGenerator.ContainerFromIndex(0)) as Panel;
            }
            if ((this._itemsPanel != null) && (this._itemsPanel is StackPanel))
            {
                this._itemsPanel.SetValue(StackPanel.OrientationProperty, this.Orientation);
            }
        }

        internal void ShowAutoCloseAreas()
        {
            if (this.AutoClose)
            {
                if (this._autoClosePopup == null)
                {
                    this.CreateAutoCloseAreas();
                }
                this.UpdateAutoCloseAreas();
                this.AttachAutoCloseAreas();
                this._autoClosePopup.IsOpen = true;
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            this.CloseMenu();
            this._lastFocus = null;
            this._isLostFocusTimerTriggerred = true;
            this._lostFocusTimer.Stop();
        }

        internal virtual void UpdateAutoCloseAreas()
        {
            if (this.IsInVisualTree())
            {
                FrameworkElement element = this.GetRootVisual() as FrameworkElement;
                Point point = base.TransformToVisual(this.GetRootVisual()).Transform(new Point(0.0, 0.0));
                Point point2 = new Point(point.X + base.ActualWidth, point.Y + base.ActualHeight);
                this._mainArea.Height = element.ActualHeight;
                this._mainArea.Width = element.ActualWidth;
                point.X = (point.X < 0.0) ? 0.0 : point.X;
                point.X = (point.X > element.ActualWidth) ? element.ActualWidth : point.X;
                point.Y = (point.Y < 0.0) ? 0.0 : point.Y;
                point.Y = (point.Y > element.ActualHeight) ? element.ActualHeight : point.Y;
                point2.X = (point2.X < 0.0) ? 0.0 : point2.X;
                point2.X = (point2.X > element.ActualWidth) ? element.ActualWidth : point2.X;
                point2.Y = (point2.Y < 0.0) ? 0.0 : point2.Y;
                point2.Y = (point2.Y > element.ActualHeight) ? element.ActualHeight : point2.Y;
                this._leftArea.Height = element.ActualHeight;
                this._leftArea.Width = point.X;
                this._rightArea.Height = element.ActualHeight;
                this._rightArea.Width = element.ActualWidth - point2.X;
                this._rightArea.SetValue(Canvas.LeftProperty, point2.X);
                this._topArea.Height = point.Y;
                this._topArea.Width = point2.X - point.X;
                this._topArea.SetValue(Canvas.LeftProperty, point.X);
                this._bottomArea.Height = element.ActualHeight - point2.Y;
                this._bottomArea.Width = point2.X - point.X;
                this._bottomArea.SetValue(Canvas.LeftProperty, point.X);
                this._bottomArea.SetValue(Canvas.TopProperty, point2.Y);
            }
        }

        internal void UpdateGroupChecks(MenuItem checkedItem)
        {
            if (!string.IsNullOrEmpty(checkedItem.GroupName) && checkedItem.IsChecked)
            {
                List<MenuItem> list = null;
                if (this._checkGRoups.TryGetValue(checkedItem.GroupName, out list))
                {
                    foreach (MenuItem item in list)
                    {
                        if (item.IsChecked && (item != checkedItem))
                        {
                            item.IsChecked = false;
                        }
                    }
                }
            }
        }

        // Properties
        public bool AutoClose
        {
            get { return (bool)GetValue(AutoCloseProperty); }
            set { SetValue(AutoCloseProperty, value); }
        }

        public bool DetectBoundaries
        {
            get { return (bool)GetValue(DetectBoundariesProperty); }
            set { SetValue(DetectBoundariesProperty, value); }
        }

        public Visibility DisabledCuesVisibility
        {
            get { return (Visibility)GetValue(DisabledCuesVisibilityProperty); }
            set { SetValue(DisabledCuesVisibilityProperty, value); }
        }

        public Style FirstLevelStyle
        {
            get { return (Style)GetValue(FirstLevelStyleProperty); }
            set { SetValue(FirstLevelStyleProperty, value); }
        }

        public Visibility FocusCuesVisibility
        {
            get { return (Visibility)GetValue(FocusCuesVisibilityProperty); }
            set { SetValue(FocusCuesVisibilityProperty, value); }
        }

        public Brush HighlightedBackground
        {
            get { return (Brush)GetValue(HighlightedBackgroundProperty); }
            set { SetValue(HighlightedBackgroundProperty, value); }
        }

        internal MenuItem HighlightedItem
        {
            get { return this._highlightedItem; }
            set
            {
                if ((this._highlightedItem != null) && (this._highlightedItem != value))
                {
                    this._highlightedItem.IsHighlighted = false;
                }
                this._highlightedItem = value;
            }
        }

        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            internal set { SetValue(IsFocusedProperty, value); }
        }

        internal bool IsSubmenuOpen
        {
            get
            {
                foreach (MenuItem item in this.MenuItems)
                {
                    if (item.IsSubmenuOpen)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        internal IList MenuItems
        {
            get
            {
                IList list = new List<object>();
                foreach (object obj2 in base.Items)
                {
                    MenuItem container = base.GetContainer(obj2) as MenuItem;
                    if (container != null)
                    {
                        list.Add(container);
                    }
                }
                return list;
            }
        }

        public int MenuOpenDelay
        {
            get { return (int)GetValue(MenuOpenDelayProperty); }
            set
            {
                this.SetMenuOpenDelayValue(value);
            }
        }

        public Style NonFirstLevelStyle
        {
            get { return (Style)GetValue(NonFirstLevelStyleProperty); }
            set { SetValue(NonFirstLevelStyleProperty, value); }
        }

        public Brush OpenedBackground
        {
            get { return (Brush)GetValue(OpenedBackgroundProperty); }
            set { SetValue(OpenedBackgroundProperty, value); }
        }

        public Orientation Orientation
        {
            get { return (Orientation)GetValue(OrientationProperty); }
            set { SetValue(OrientationProperty, value); }
        }

        public Style SeparatorStyle
        {
            get { return (Style)GetValue(SeparatorStyleProperty); }
            set { SetValue(SeparatorStyleProperty, value); }
        }

        public double SubMenuMaxHeight
        {
            get { return (double)GetValue(SubMenuMaxHeightProperty); }
            set { SetValue(SubMenuMaxHeightProperty, value); }
        }
    }
}
